package com.bwie.es.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bwie.common.domain.request.ProductRequest;
import com.bwie.common.result.PageResult;
import com.bwie.common.result.Result;
import com.bwie.common.utils.StringUtils;
import com.bwie.es.service.EsService;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class EsServiceImpl implements EsService {
    private static final String INDEX_NAME="product";
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public Result<PageResult<ProductRequest>> search(ProductRequest productRequest) {
        //创建初始化值
        long total=0;
        //获取一个集合
        ArrayList<ProductRequest> list = new ArrayList<>();
        //创建一个搜索对象并将索引放入
        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        //创建一个搜索数据对象 获取高亮搜索 分页
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //创建一个动态搜索对象
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //商品列表商品名称使用ES进行商品搜索
        if (!StringUtils.isBlank(productRequest.getProductName())) {
            boolQueryBuilder.must(QueryBuilders.matchQuery("productName",productRequest.getProductName()));
        }
        //反序列化值
        searchSourceBuilder.query(boolQueryBuilder);
        //设置分页
        searchSourceBuilder.from((productRequest.getPageNum()-1)*productRequest.getPageSize());
        searchSourceBuilder.size(productRequest.getPageSize());
        //搜索关键字进行高亮显示，分词器使用IK中文分词器
        searchSourceBuilder.highlighter(new HighlightBuilder()
                .field("productName")
                .preTags("<span style=\"color: red\">")
                .postTags("</span>"));
        //将搜索的数据都放入搜索对象中
        searchRequest.source(searchSourceBuilder);
        try {
            //获取反序列化的值
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits hits = search.getHits();
             total = (int) hits.getTotalHits().value;
            for (SearchHit hit : hits) {
                String sourceAsString = hit.getSourceAsString();
                ProductRequest product = JSON.parseObject(sourceAsString, ProductRequest.class);
                product.setProductId(Integer.valueOf(hit.getId()));
                //获取高亮
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                //判断高亮是否存在
                if (null != highlightFields){
                    HighlightField productName = highlightFields.get("productName");
                    //判断高亮搜索字段是否存在
                    if (null != productName) {
                        Text[] fragments = productName.getFragments();
                        String str="";
                        for (Text fragment : fragments) {
                            str+=fragment;
                        }
                        product.setProductName(str);
                    }
                }
                list.add(product);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return PageResult.toResult(total,list);
    }

    @Override
    public void insertBatch(List<ProductRequest> ProductRequests) {
        try {
            BulkRequest bulkRequest = new BulkRequest();
            ProductRequests.forEach(product -> {
                bulkRequest.add(new IndexRequest(INDEX_NAME)
                        .id(product.getProductId()+"")
                        .source(JSONObject.toJSONString(product), XContentType.JSON));
            });
            restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void deleteCourseEs(){
        DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(INDEX_NAME);
        deleteByQueryRequest.setQuery(QueryBuilders.matchAllQuery());
        try {
            restHighLevelClient.deleteByQuery(deleteByQueryRequest,RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
